package com.wjk.cms.controller;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.wjk.cms.auth.AuthContext;
import com.wjk.cms.common.Result;
import com.wjk.cms.exception.ApplicationException;
import com.wjk.cms.exception.AuthenticationException;

import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    private static final String DEFAULT_MESSAGE = "服务器出错";

    @Value("${app.upload-folder-path}")
    private String uploadFolderPath;

    @ResponseBody
    @ExceptionHandler(AuthenticationException.class)
    public Result handleAuthenticationException(AuthenticationException e) {
        log.info("全局异常(AuthenticationException) - " + e.getMessage());
        return Result.error(e.getCode(), getMessage(e.getMessage()));
    }

    @ResponseBody
    @ExceptionHandler(ApplicationException.class)
    public Result handleApplicationException(ApplicationException e) {
        log.info("全局异常(ApplicationException) - " + e.getMessage(), e);
        return Result.error(e.getCode(), getMessage(e.getMessage()));
    }




    @ResponseBody
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        HttpServletRequest httpServletRequest = getHttpServletRequest();
        log.info("全局异常(Exception) - "+httpServletRequest.getRequestURI() + e.getMessage(), e);
        if (!isIgnoredException(e, httpServletRequest)) {
            String access_token = "41e54f6b56a929fb59c05473b12df180eff7f4efb43f783b7192d487e17a4370";
            String serverUrl = "https://oapi.dingtalk.com/robot/send?access_token=" + access_token;
            DingTalkClient client = new DefaultDingTalkClient(serverUrl);
            OapiRobotSendRequest request = new OapiRobotSendRequest();
            request.setMsgtype("text");
            OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
            String prompt = (httpServletRequest == null ? "接口[null]" : "接口[" + httpServletRequest.getMethod() + " " + httpServletRequest.getRequestURI() + "]") + " - User[" + AuthContext.get() + "]";
            if (httpServletRequest != null) {
                prompt += "\nUser-Agent: " + httpServletRequest.getHeader("User-Agent");
                prompt += "\nReferer: " + httpServletRequest.getHeader("Referer");
                prompt += "\nchannel: " + httpServletRequest.getHeader("channel");
            }
            text.setContent("【SCM】发生异常 - " + e.getMessage() + "\n" + prompt + "\n" + ExceptionUtils.getStackTrace(e));
            request.setText(text);
//            try {
//                client.execute(request);
//            } catch (ApiException ex) {
//                log.error("发送钉钉消息失败 - " + ex.getMessage(), ex);
//            }
        }
        return Result.error(getMessage(e.getMessage()));
    }

    private boolean isIgnoredException(Exception e, HttpServletRequest httpServletRequest) {
        if (e instanceof HttpRequestMethodNotSupportedException) {
            return true;
        }
        if (e instanceof ClientAbortException) {
            return true;
        }
        String method = httpServletRequest.getMethod();
        String requestUri = httpServletRequest.getRequestURI();
        if ("/m/public/scm/poster".equals(requestUri)) {
            if ("pos < flushedPos!".equals(e.getMessage())) {
                return true;
            }
        }
        return false;
    }

    private String getMessage(String message) {
        return StringUtils.isEmpty(message) ? DEFAULT_MESSAGE : message;
    }

    private HttpServletRequest getHttpServletRequest() {
        try {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        } catch (Exception e) {
        }
        return null;
    }

}
